library Dialog /* v.1.1.0.0
    **************************************************
    *
    *   A struct wrapper for easy dialog creation.
    *
    **************************************************
    *
    */  requires Table  /* [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
    * 
    **************************************************
    *
    *   struct Dialog 
    *
    *       static method create() returns thistype
    *           
    *           Creates a new dialog and returns its instance.
    *
    *       method method setMessage takes string s
    *
    *           Sets the title message for the dialog.
    *
    *       method addButton(integer idx, string text, integer hotkey ) returns button
    *
    *           Adds a button to the dialog that reads <text>.
    *           The hotkey serves as a shortcut to press a dialog 
    *           button. Example input: 'a', 'b', 512 (esc).
    *
    *       method display( player p, boolean flag )
    *           
    *           Shows/hides a dialog for a particular player. 
    *
    *       method displayAll( boolean flag )
    *
    *           Shows/hides a dialog for all players. 
    *
    *       method clear()
    *   
    *           Clears a dialog of its message and buttons.
    *
    *       method destroy()
    *
    *           Destroys a dialog and its instance.
    *
    *   -- Event API --
    *
    *       method setClickAction( code c )
    *
    *           Registers when a dialog button is clicked.
    *       
    *       static method get takes dialog dlg returns Dialog
    *       method isClicked takes integer idx returns boolean 
    *
    *            Event responses.
    *
    **************************************************
    *
    *   Constants - Credits to DysfunctionaI for the list!
    */
    globals
        constant integer KEY_SPACEBAR          = 32

        constant integer KEY_0 = 48
        constant integer KEY_1 = 49
        constant integer KEY_2 = 50
        constant integer KEY_3 = 51
        constant integer KEY_4 = 52
        constant integer KEY_5 = 53
        constant integer KEY_6 = 54
        constant integer KEY_7 = 55
        constant integer KEY_8 = 56
        constant integer KEY_9 = 57
    
        constant integer KEY_A = 65
        constant integer KEY_B = 66
        constant integer KEY_C = 67
        constant integer KEY_D = 68
        constant integer KEY_E = 69
        constant integer KEY_F = 70
        constant integer KEY_G = 71
        constant integer KEY_H = 72
        constant integer KEY_I = 73
        constant integer KEY_J = 74
        constant integer KEY_K = 75
        constant integer KEY_L = 76
        constant integer KEY_M = 77
        constant integer KEY_N = 78
        constant integer KEY_O = 79
        constant integer KEY_P = 80
        constant integer KEY_Q = 81
        constant integer KEY_R = 82
        constant integer KEY_S = 83
        constant integer KEY_T = 84
        constant integer KEY_U = 85
        constant integer KEY_V = 86
        constant integer KEY_W = 87
        constant integer KEY_X = 88
        constant integer KEY_Y = 89
        constant integer KEY_Z = 90
        
        /* Number Pad */
        constant integer KEY_NUMPAD_0          = 257
        constant integer KEY_NUMPAD_1          = 258
        constant integer KEY_NUMPAD_2          = 259
        constant integer KEY_NUMPAD_3          = 260
        constant integer KEY_NUMPAD_4          = 261
        constant integer KEY_NUMPAD_5          = 262
        constant integer KEY_NUMPAD_6          = 263
        constant integer KEY_NUMPAD_7          = 264
        constant integer KEY_NUMPAD_8          = 265
        constant integer KEY_NUMPAD_9          = 266
        constant integer KEY_NUMPAD_PLUS       = 267
        constant integer KEY_NUMPAD_MINUS      = 268
        constant integer KEY_NUMPAD_ASTERISK   = 269 
        constant integer KEY_NUMPAD_SLASH      = 270
        constant integer KEY_NUMPAD_PERIOD     = 271
        
        constant integer KEY_EQUALS            = 272
        constant integer KEY_MINUS             = 273
        constant integer KEY_LEFT_BRACKET      = 274
        constant integer KEY_RIGHT_BRACKET     = 275
        constant integer KEY_BACKSLASH         = 276
        constant integer KEY_SEMICOLON         = 277
        constant integer KEY_APOSTROPHE        = 278
        constant integer KEY_COMMA             = 279
        constant integer KEY_PERIOD            = 280   
        constant integer KEY_SLASH             = 281
        constant integer KEY_ESC               = 512
        constant integer KEY_BACKSPACE         = 514
        
        /* Arrows */
        constant integer KEY_LEFT_ARROW        = 516
        constant integer KEY_UP_ARROW          = 517
        constant integer KEY_RIGHT_ARROW       = 518
        constant integer KEY_DOWN_ARROW        = 519
        
        constant integer KEY_INSERT            = 520
        constant integer KEY_DELETE            = 521
        constant integer KEY_HOME              = 522
        constant integer KEY_END               = 523
        constant integer KEY_PAGE_UP           = 524
        constant integer KEY_PAGE_DOWN         = 525
        constant integer KEY_CAPS_LOCK         = 526
        constant integer KEY_NUM_LOCK          = 527
        constant integer KEY_SCROLL_LOCK       = 528
        constant integer KEY_PAUSE             = 529
        
        /* Function Buttons */
        constant integer KEY_F1                = 768
        constant integer KEY_F2                = 769
        constant integer KEY_F3                = 770
        constant integer KEY_F4                = 771
        constant integer KEY_F5                = 772
        constant integer KEY_F6                = 773
        constant integer KEY_F7                = 774
        constant integer KEY_F8                = 775
        constant integer KEY_F9                = 776
        constant integer KEY_F10               = 777
        constant integer KEY_F11               = 778
        constant integer KEY_F12               = 779
    endglobals
    /*
    **************************************************/
    globals
        private Table dlgTb = 0
    endglobals
    
    private module DialogInit 
        private static method onInit takes nothing returns nothing 
            set dlgTb = Table.create()
        endmethod
    endmodule

    struct Dialog
        private dialog dlg
        private trigger clickTr
        private string msg

        integer data = 0
        
        // GetClickedDialog()
        static method get takes dialog dlg returns thistype 
            return dlgTb[GetHandleId(dlg)]
        endmethod
        
        method setMessage takes string text returns nothing 
            set this.msg = text
        endmethod

        method appendHotkey takes string text, string hotkey returns string
            return text + " |cffffcc00(" + hotkey + ")|r"
        endmethod

        method addButton takes string text, integer hotkey returns button
            return DialogAddButton(this.dlg, text, hotkey)
        endmethod
        
        method display takes player p, boolean flag returns nothing
            call DialogDisplay(p, this.dlg, flag)
            call DialogSetMessage(this.dlg, this.msg)
        endmethod

        method displayAll takes boolean flag returns nothing
            call display(GetLocalPlayer(), flag)
        endmethod
        
        method clear takes nothing returns nothing
            call DialogClear(this.dlg)
            set this.msg = ""
        endmethod
        
        method setClickAction takes code c returns nothing
            if this.clickTr == null then
                set dlgTb[GetHandleId(this.dlg)] = this
                set this.clickTr = CreateTrigger()
                call TriggerRegisterDialogEvent(this.clickTr, this.dlg)
            endif
            call TriggerAddCondition(this.clickTr, Condition(c))
        endmethod
        
        method destroy takes nothing returns nothing 
            debug if this.dlg == null then
            debug     call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "[Dialog] Attempted to destroy null dialog.")
            debug endif
            
            if this.clickTr != null then
                call DestroyTrigger(this.clickTr)
                call dlgTb.remove(GetHandleId(this.dlg))
                set this.clickTr = null
            endif

            call this.clear()
            call DialogDestroy(this.dlg)
            set this.dlg = null
            call this.deallocate()
        endmethod
    
        static method create takes nothing returns thistype
            local thistype this = thistype.allocate()
            set this.dlg = DialogCreate()
            return this
        endmethod
        
        implement DialogInit
    endstruct
        
endlibrary